<template>
    <div>
        <div class="addcargo">
            <h3 class="form-title">货物明细</h3>
            <Button type="primary" :disabled="disabled" size="small" @click="operateData(addCargoData)">新增</Button>
            <Button type="primary" :disabled="disabled" size="small" @click="operateData(copyCargoData)">复制</Button>
            <Button type="primary" :disabled="disabled" size="small" @click="operateData(delCargoData)">删除</Button>
            <Button type="primary" :disabled="disabled" size="small" @click="operateData(handleInsert)">插入</Button>
            <Button type="primary" :disabled="disabled" size="small" @click="operateData(handleMoveUp)">上移</Button>
            <Button type="primary" :disabled="disabled" size="small" @click="operateData(handleMoveDown)">下移</Button>
        </div>
        <div class="cargo-details no-padding">
            <el-table
                id="cargo_table"
                class="table-small"
                ref="cargoTable"
                border
                stripe
                highlight-current-row
                :data="cargoData"
                :header-cell-class-name="bindCellIndex"
                @row-click="rowClick"
                @row-dblclick="rowDblClick"
                @selection-change="handleSelectionChange"
            >
                <!-- 多选 -->
                <el-table-column type="selection" width="30" align="center"></el-table-column>
                <!-- 序号 -->
                <el-table-column label="序号" type="index" width="35" align="center"></el-table-column>
                <!-- 备案序号 -->
                <el-table-column label="备案序号" width="60" align="center">
                    <template slot="header" slot-scope="scope">
                        <span :class="{required: ieFlag=='E'}">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <Input
                            :class="{
                                'required-input-bg': ieFlag === 'E'
                            }"
                            size="small"
                            v-if="editIndex === $index"
                            v-model.trim="editData.putrecSeqno"
                            :maxlength="19"
                        ></Input>
                        <div class="text-ellipsis" :title="row.putrecSeqno" v-else>{{row.putrecSeqno}}</div>
                    </template>
                </el-table-column>
                <!-- 商品料号 -->
                <el-table-column label="商品料号" width="110" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <Input
                            class="required-input-bg"
                            size="small"
                            v-if="editIndex === $index"
                            v-model.trim="editData.gdsMtno"
                        ></Input>
                        <div class="text-ellipsis" :title="row.gdsMtno" v-else>{{row.gdsMtno}}</div>
                    </template>
                </el-table-column>
                <!-- 商品编码 -->
                <el-table-column label="商品编码" width="90" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <Input
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            :maxlength="10"
                            v-model.trim="editData.gdecd"
                            @on-enter="handleGoodsCodingBlur($event, $index)"
                        ></Input>
                        <div class="text-ellipsis" :title="row.gdecd" v-else>{{row.gdecd}}</div>
                    </template>
                </el-table-column>
                <!-- 商品名称 -->
                <el-table-column label="商品名称" width="100" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <Input size="small" class="required-input-bg" v-if="editIndex === $index" @on-enter="handleGdsNmEnter" v-model.trim="editData.gdsNm"></Input>
                        <div class="text-ellipsis" :title="row.gdsNm" v-else>{{row.gdsNm}}</div>
                    </template>
                </el-table-column>
                <!-- 规格型号 -->
                <el-table-column label="规格型号" width="140" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <Input
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            v-model.trim="editData.gdsSpcfModelDesc"
                            @click.native="openGoodsModel"
                            readonly
                        ></Input>
                        <div class="text-ellipsis" :title="row.gdsSpcfModelDesc" v-else>{{row.gdsSpcfModelDesc}}</div>
                    </template>
                </el-table-column>
                <!-- 币制 -->
                <el-table-column label="币制" width="50" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <RemoteSearch
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            v-model="editData.dclCurrcd"
                            :list="customsBZData"
                            keywordFiled="shortName"
                            valueField="dataSecondType"
                            :labelFieldList="['dataSecondType', 'shortName']"
                            @on-get-name="v => editData.dclCurrcdCHN = v"
                        >
                        </RemoteSearch>
                        <div class="text-ellipsis" :title="row.dclCurrcdCHN" v-else>{{row.dclCurrcdCHN}}</div>
                    </template>
                </el-table-column>
                <!-- 申报数量 -->
                <el-table-column label="申报数量" width="68" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <Input
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            v-model.number="editData.dclQty"
                            @on-blur="handleChangedclQty"
                        ></Input>
                        <div class="text-ellipsis" v-else :title="row.dclQty">{{row.dclQty}}</div>
                    </template>
                </el-table-column>
                <!-- 申报计量单位 -->
                <el-table-column label="申报计量单位" width="90" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <RemoteSearch
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            v-model="editData.dclUnitcd"
                            :list="unitList"
                            keywordFiled="dataName"
                            valueField="dataCode"
                            :labelFieldList="['dataCode', 'dataName']"
                            @on-get-name="v => editData.dclUnitcdCHN = v"
                            @get-all="setLawfSecdQty"
                        >
                        </RemoteSearch>
                        <div class="text-ellipsis" :title="row.dclUnitcdCHN" v-else>{{row.dclUnitcdCHN}}</div>
                    </template>
                </el-table-column>
                <!-- 法定数量 -->
                <el-table-column label="法定数量" width="65" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <Input
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            v-model.number="editData.lawfQty"
                            @on-blur="checkFirstGqty"
                        ></Input>
                        <div class="text-ellipsis" v-else :title="row.lawfQty">{{row.lawfQty}}</div>
                    </template>
                </el-table-column>
                <!-- 法定计量单位 -->
                <el-table-column label="法定计量单位" width="82" align="center">
                    <template slot-scope="{row, $index}">
                        <Input size="small" v-if="editIndex === $index" v-model="editData.lawfUnitcdCHN" disabled />
                        <div class="text-ellipsis" :title="row.lawfUnitcdCHN" v-else>{{row.lawfUnitcdCHN}}</div>
                    </template>
                </el-table-column>
                <!-- 第二法定数量 -->
                <el-table-column label="第二法定数量" width="80" align="center">
                    <template slot-scope="{row, $index}">
                        <Input
                            size="small"
                            v-if="editIndex === $index"
                            :disabled="!editData.secdLawfUnitcd"
                            v-model.number="editData.secdLawfQty"
                            @on-blur="checkSecondGqty"
                        ></Input>
                        <div class="text-ellipsis" v-else :title="row.secdLawfQty">{{row.secdLawfQty}}</div>
                    </template>
                </el-table-column>
                <!-- 法定第二计量单位 -->
                <el-table-column label="法定第二计量单位" width="103" align="center">
                    <template slot-scope="{row, $index}">
                        <Input size="small" v-if="editIndex === $index" v-model="editData.secdLawfUnitcdCHN" disabled />
                        <div class="text-ellipsis" v-else :title="row.secdLawfUnitcdCHN">{{row.secdLawfUnitcdCHN}}</div>
                    </template>
                </el-table-column>
                <!-- 企业申报单价 -->
                <el-table-column label="企业申报单价" width="87" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <Input
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            v-model.number="editData.dclUprcAmt"
                            @on-blur="handleChangePrice"
                        ></Input>
                        <div class="text-ellipsis" v-else :title="row.dclUprcAmt">{{row.dclUprcAmt}}</div>
                    </template>
                </el-table-column>
                <!-- 企业申报总价 -->
                <el-table-column label="企业申报总价" width="88" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <Input
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            v-model.number="editData.dclTotalAmt"
                            @on-blur="handleChangeTotal"
                        ></Input>
                        <div class="text-ellipsis" v-else :title="row.dclTotalAmt">{{row.dclTotalAmt}}</div>
                    </template>
                </el-table-column>
                <!-- 原产国(地区) -->
                <el-table-column label="原产国(地区)" width="87" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <RemoteSearch
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            v-model="editData.natcd"
                            :list="countryRegionList"
                            keywordFiled="dataName"
                            valueField="dataSecondType"
                            :labelFieldList="['dataSecondType', 'dataName']"
                            @on-get-name="v => editData.natcdCHN = v"
                        >
                        </RemoteSearch>
                        <div class="text-ellipsis" v-else :title="row.natcdCHN">{{row.natcdCHN}}</div>
                    </template>
                </el-table-column>
                <!-- 毛重 -->
                <el-table-column label="毛重" width="40" align="center">
                    <template slot-scope="{row, $index}">
                        <Input size="small" v-if="editIndex === $index" v-model.number="editData.grossWt" />
                        <div class="text-ellipsis" v-else :title="row.grossWt">{{row.grossWt}}</div>
                    </template>
                </el-table-column>
                <!-- 净重 -->
                <el-table-column label="净重" width="40" align="center">
                    <template slot-scope="{row, $index}">
                        <Input size="small" v-if="editIndex === $index" v-model.number="editData.netWt" />
                        <div class="text-ellipsis" v-else :title="row.netWt">{{row.netWt}}</div>
                    </template>
                </el-table-column>
                <!-- 最终目的国(地区) -->
                <el-table-column label="最终目的国(地区)" width="112" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <RemoteSearch
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            v-model="editData.destinationNatcd"
                            :list="countryRegionList"
                            keywordFiled="dataName"
                            valueField="dataSecondType"
                            :labelFieldList="['dataSecondType', 'dataName']"
                            @on-get-name="v => editData.destinationNatcdCHN = v"
                        >
                        </RemoteSearch>
                        <div class="text-ellipsis" v-else :title="row.destinationNatcdCHN">{{row.destinationNatcdCHN}}</div>
                    </template>
                </el-table-column>
                <!-- 征免方式 -->
                <el-table-column label="征免方式" width="65" align="center">
                    <template slot="header" slot-scope="scope">
                        <span class="required">{{scope.column.label}}</span>
                    </template>
                    <template slot-scope="{row, $index}">
                        <RemoteSearch
                            size="small"
                            class="required-input-bg"
                            v-if="editIndex === $index"
                            v-model="editData.lvyrlfModecd"
                            :list="cutModeList"
                            keywordFiled="dataName"
                            valueField="dataCode"
                            :labelFieldList="['dataCode', 'dataName']"
                            @on-get-name="v => editData.lvyrlfModecdCHN = v"
                        >
                        </RemoteSearch>
                        <div class="text-ellipsis" v-else :title="row.lvyrlfModecdCHN">{{row.lvyrlfModecdCHN}}</div>
                    </template>
                </el-table-column>
                <!-- 单耗版本号 -->
                <el-table-column label="单耗版本号" width="72" align="center">
                    <template slot-scope="{row, $index}">
                        <Input size="small" v-if="editIndex === $index" v-model.trim="editData.ucnsVerno" :maxlength="8" @on-enter="saveCargoData($index,'next')"></Input>
                        <div class="text-ellipsis" v-else :title="row.ucnsVerno">{{row.ucnsVerno}} </div>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 操作栏 -->
            <div class="table-side">
                <table cellspacing="0" cellpadding="0" border="0">
                    <thead>
                        <tr>
                            <th>
                                <div>操作</div>
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(item, index) in cargoData" :key="index">
                            <td>
                                <div class="table-action">
                                    <template v-if="editIndex === index">
                                        <i class="table-icon t-save-icon" title="保存" @click="saveCargoData(index,'save')"></i>
                                        <i class="table-icon t-cancel-icon" title="取消" @click="cancelEditCargoData(index)"></i>
                                    </template>
                                    <template v-else>
                                        <i class="table-icon t-edit-icon" :class="{disabled: disabled}" title="编辑" @click="!disabled && operateData(editCargoData, index)"></i>
                                        <i class="table-icon t-del-icon" :class="{disabled: disabled}" title="删除" @click="!disabled && operateData(deleteCargoData, index)"></i>
                                    </template>
                                </div>
                            </td>
                        </tr>
                        <tr v-if="cargoData.length === 0">
                            <td></td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <GoodsModal
            v-model="goodsModalVisible"
            :coding="goodsCoding"
            @on-ok="selectGoods"
            @on-cancel="cancelSelect"
        ></GoodsModal>

        <!--获取申报要素-->
        <detailsModal ref="detailsModalRef" @saveDetail="saveDetail"/>

    </div>
</template>
<script>
import { focusIndexInput, nextFocus } from '@/libs/ivuDom.js'
import { on, evenRound } from '@/libs/tools'
import { getDicByKey } from '@/libs/getDicDataList'
import GoodsModal from './goods-modal'
import cargoRules from '../js/cargo-rules'
import detailsModal from '@/view/customs-manage/components/detailsModal'

import { managementFuzzyQuery } from '@/api/warehouse' // 海关编码查询
// 单个货物的属性key集合
const cargoKeys = [
    'invtGoodsId',
    'putrecSeqno',
    'gdsMtno',
    'gdecd',
    'gdsNm',
    'gdsSpcfModelDesc',
    'dclCurrcd',
    'dclUnitcd',
    'lawfUnitcd',
    'secdLawfUnitcd',
    'dclQty',
    'lawfQty',
    'secdLawfQty',
    'dclUprcAmt',
    'dclTotalAmt',
    'natcd',
    'grossWt',
    'netWt',
    'destinationNatcd',
    'lvyrlfModecd',
    'ucnsVerno'
]
// 货物对应下拉框label的key集合
const cargoLabelkeys = [
    'dclCurrcdCHN',
    'dclUnitcdCHN',
    'natcdCHN',
    'destinationNatcdCHN',
    'lvyrlfModecdCHN',
    'lawfUnitcdCHN',
    'secdLawfUnitcdCHN'
]
export default {
    components: {
        detailsModal,
        GoodsModal
    },
    props: {
        disabled: {
            default: false,
            type: Boolean
        },
        // 进出口类型
        ieFlag: {
            type: String,
            default: 'I'
        },
        // 外部的核注清单企业内部编号
        etpsNo: {
            type: String,
            default: ''
        },
        // 业务类型
        templateType: {
            default: '',
            type: String
        }
    },
    data () {
        let editData = {}
        cargoLabelkeys.concat(cargoKeys).forEach(key => {
            editData[key] = ''
        })
        return {
            cutModeList: [], // 征免方式
            countryRegionList: [], // 国家
            unitList: [], // 计量单位
            customsBZData: [], // 币制
            cargoData: [],
            goodsModalVisible: false, // 商品弹窗状态
            goodsCoding: '', // 传递给弹窗的编码
            editIndex: -1, // 正在编辑的货物序号
            editData
        }
    },
    mounted () {
        this.$nextTick(_ => {
            this.bindEvent()
        })
        this.getBZList()
        this.getUnitList()
        this.getCountryRegionList()
        this.getCutModeList()
    },
    watch: {
        // 监听 外部的核注清单企业内部编号 改变
        etpsNo (v) {
            this.handleEtpsNoChange(v)
        },
        // 监听商品列表长度并触发外部changLen事件
        'cargoData.length': {
            handler (v) {
                this.$emit('changeLen', v)
            },
            immediate: true
        }
    },
    methods: {
        // 绑定表格 列 序号
        bindCellIndex ({ column, columnIndex }) {
            column.index = columnIndex
            return ''
        },
        handleGdsNmEnter (event) {
            event.stopPropagation()
            this.$nextTick(_ => {
                // 选中商品规格
                focusIndexInput(5, this.inputs)
            })
        },
        // 获取征免方式
        getCutModeList () {
            return getDicByKey('DUTY_MODE').then(list => {
                this.cutModeList = list
            })
        },
        // 获得国家数据字典
        getCountryRegionList () {
            return getDicByKey('COUNTRY_REGION').then(list => {
                this.countryRegionList = list
            })
        },
        // 获取计量单位
        getUnitList () {
            return getDicByKey('UNIT').then(list => {
                this.unitList = list
            })
        },
        // 获取币制关别
        getBZList () {
            return getDicByKey('CURRENCY_CODE').then(list => {
                this.customsBZData = list
            })
        },
        // 默认选中一个数据编辑 没有数据就新增
        defaultFocus () {
            const len = this.cargoData.length
            if (len) {
                this.editIndex < 0
                    ? this.editCargoData(0)
                    : this.inputs && focusIndexInput(0, this.inputs)
            } else {
                this.addCargoData()
            }
        },
        // 查找需要绑定回车事件的input
        findInputs (focus = 0) {
            this.$nextTick(_ => {
                this.inputs = document.querySelectorAll(
                    '#cargo_table .el-table__body input[type=text]'
                )
                setTimeout(_ => {
                    focusIndexInput(focus, this.inputs)
                }, 50)
            })
        },
        // 绑定表格 input 回车调整下一个input事件
        bindEvent () {
            const self = this
            on(
                document.querySelector('#cargo_table .el-table__body'),
                'keyup',
                function next (event) {
                    ;
                    if (event.keyCode === 13) {
                        nextFocus(event, self.inputs)
                    }
                }
            )
        },
        // 初始化所有远程下拉选项 避免频繁调用接口查数据
        initEditRowData (cargo, index) {
            this.setEditData(cargo)
        },
        setEditData (data) {
            cargoLabelkeys.concat(cargoKeys).forEach(key => {
                this.editData[key] = data[key] || ''
            })
        },
        // 复制数据
        copyCargoData () {
            if (this.selectList && this.selectList.length) {
                const _key = new Date().getTime()
                this.selectList.forEach((item, index) => {
                    let data = JSON.parse(JSON.stringify(item))
                    data.invtGoodsId = ''
                    data._key = _key + index // 设置唯一标识(批量删除的筛选条件TPAD:1007408)
                    this.cargoData.push(data)
                })
                // 初始化商品料号
                this.initCargoGdsMtno()
                // 复制成功后清空多选
                this.selectList = []
                this.$refs.cargoTable && this.$refs.cargoTable.clearSelection()
            } else {
                this.$Message.warning('请选择需要复制的货物数据')
            }
        },
        // 新增货物数据 inde 新建的位置 默认最后
        addCargoData (index = null) {
            this.isNewFlag = true
            const obj = {}
            const def = this.defGoodsInfo || {}
            cargoLabelkeys.concat(cargoKeys).forEach(key => {
                obj[key] = def[key] || ''
            })
            const isNumber = typeof index === 'number'
            obj.gdsMtno = this.getSysGdsMtno(isNumber ? index + 1 : index)
            obj._key = new Date().getTime() // 设置唯一标识(批量删除的筛选条件TPAD:1007408)
            isNumber
                ? this.cargoData.splice(index, 0, obj)
                : this.cargoData.push(obj)
            // 更新暂存数据值
            this.editIndex = isNumber ? index : this.cargoData.length - 1
            this.findInputs()
            this.initEditRowData(obj)
        },
        // 编辑货物数据
        editCargoData (index, focus = 0) {
            this.isNewFlag = false
            // 初始化下拉框
            const obj = this.cargoData[index]
            this.editIndex = index
            // 查找需要回车跳转的input
            this.findInputs(focus)
            this.initEditRowData(obj)
        },
        // 保存货物数据
        saveCargoData (index, type) {
            if (this.checkCargoData(this.editData)) {
                const { gdsMtno } = this.editData
                // fix:商品料号校验bug(入仓是不能重复，出仓可以重复)
                // 判断是否插入的数据保存
                const isInsert = this.isNewFlag && index < this.cargoData.length - 1
                // 进口类别时 插入的数据会重新排序商品料号 不需要判断商品料号是否重复
                if (this.ieFlag === 'I' && !isInsert && gdsMtno) {
                    // 判断商品料号是否重复
                    const list = this.cargoData.slice()
                    list.splice(index, 1, {})
                    const gIndex = list.findIndex(obj => obj.gdsMtno === gdsMtno)
                    if (gIndex > -1) {
                        this.$Message.warning(`第 ${index + 1}，${gIndex + 1} 行的商品料号相同，请修改`)
                        return
                    }
                }
                cargoLabelkeys.concat(cargoKeys).forEach(key => {
                    this.cargoData[index][key] = this.editData[key]
                })
                isInsert && this.initCargoGdsMtno() // 插入数据后重新排序
                this.editIndex = -1
                if (type === 'next') {
                    this.addCargoData()
                }
            }
        },
        // 重置商品所有的商品料号
        initCargoGdsMtno () {
            if (this.ieFlag === 'I' && this.etpsNo) {
                this.cargoData.forEach((item, index) => {
                    const code = ('000' + (index + 1)).substr(-3)
                    item.gdsMtno = this.etpsNo + code
                })
            }
        },
        // 取消编辑货物数据
        cancelEditCargoData (index) {
            // 是新增的则删除 否则 回退到之前数据
            if (this.isNewFlag) {
                this.cargoData.splice(index, 1)
                // 新增的取消相当于删除了一条数据需要执行删除成功方法
                this.handleDelSuccess(index)
            }
            this.editIndex = -1
        },
        // 删除货物数据
        deleteCargoData (index) {
            this.cargoData.splice(index, 1)
            this.editIndex = -1
            // 初始化商品料号
            this.initCargoGdsMtno()
            this.handleDelSuccess(index)
        },
        // 批量删除
        delCargoData () {
            if (this.selectList && this.selectList.length) {
                // 根据唯一标识_key删除不需要的数据(批量删除TPAD:1007408)
                const keys = this.selectList.map(item => item._key)
                const list = this.cargoData.filter(item => keys.indexOf(item._key) < 0)
                this.cargoData = list
                this.selectList = []
                // 批量删除清空当前选中的数据
                this.clearTableCurrentRow()
                // 初始化商品料号
                this.initCargoGdsMtno()
            } else {
                this.$Message.warning('请选择需要删除的货物数据')
            }
        },
        // 处理删除数据成功
        handleDelSuccess (index) {
            console.log(this._cargoSelectIndex, index)
            // 判断当前选中行号是否存在
            if (this._cargoSelectIndex > index) {
                this._cargoSelectIndex--
            } else if (this._cargoSelectIndex === index) {
                this._cargoSelectIndex = -1
            }
        },
        // 插入
        handleInsert () {
            const index = this._cargoSelectIndex
            if (typeof index === 'number' && index >= 0) {
                this.addCargoData(index)
                this._cargoSelectIndex++
            } else {
                this.$Message.warning('请选择需要插入的数据')
            }
        },
        // 上移
        handleMoveUp () {
            const index = this._cargoSelectIndex
            if (typeof index === 'number' && index >= 0) {
                if (index <= 0) {
                    this.$Message.warning('已经是到顶了，不能在上移了！')
                    return false
                }
                const start = this.cargoData[index]
                const end = this.cargoData[index - 1]
                this.cargoData.splice(index - 1, 2, start, end)
                this._cargoSelectIndex = index - 1
                // 初始化商品料号
                this.initCargoGdsMtno()
            } else {
                this.$Message.warning('请选择需要移动的数据')
            }
        },
        // 下移
        handleMoveDown () {
            const index = this._cargoSelectIndex
            if (typeof index === 'number' && index >= 0) {
                const len = this.cargoData.length - 1
                if (index >= len) {
                    this.$Message.warning('已经是到底了，不能在下移了！')
                    return false
                }
                const start = this.cargoData[index + 1]
                const end = this.cargoData[index]
                this.cargoData.splice(index, 2, start, end)
                this._cargoSelectIndex = index + 1
                // 初始化商品料号
                this.initCargoGdsMtno()
            } else {
                this.$Message.warning('请选择需要移动的数据')
            }
        },
        // 单击选中
        rowClick (row) {
            const index = this.cargoData.findIndex(item => item._key == row._key)
            this._cargoSelectIndex = index
        },
        // 双击编辑
        rowDblClick (item, column) {
            const index = this._cargoSelectIndex
            if (this.disabled || this.editIndex === index) return
            const focusIndex = column.index - 2 // bindCellIndex 方法 设置列的序号 根据序号foucs当前点击的数据输入框
            this.operateData(() => {
                this.editCargoData(index, focusIndex)
            }, index)
        },
        // 清空table 选中行
        clearTableCurrentRow () {
            // 批量删除清空当前选中的数据
            this._cargoSelectIndex = -1
            this.$refs.cargoTable && this.$refs.cargoTable.setCurrentRow()
        },
        // 表格多选事件
        handleSelectionChange (list) {
            this.selectList = list
        },
        // 操作数据前 先判断数据再执行操作（只能同时编辑或者新增一个数据）
        operateData (fn, ...arg) {
            if (this.editIndex < 0) {
                fn && fn(...arg)
            } else {
                this.$Message.warning('请保存正在编辑的数据')
            }
        },
        // 保存前检查数据
        checkCargoData (data) {
            const errors = []
            Object.keys(cargoRules).forEach(key => {
                const err = cargoRules[key].call(this, data[key], this.editData)
                err && errors.push(err)
            })
            if (errors.length) {
                this.$Modal.warning({
                    width: '450px',
                    title: '请检查货物数据',
                    content: errors.join('<br>')
                })
            }
            return errors.length === 0
        },
        // 取消选择
        cancelSelect () {
            this.$nextTick(_ => {
                // 选中商品规格
                focusIndexInput(4, this.inputs)
            })
        },
        // 选择商品
        selectGoods (goods) {
            this.editData.gdecd = goods.codeTs
            // this.editData.gdsNm = goods.goodsName
            this.editData.lawfUnitcd = goods.firstUnit
            this.editData.lawfUnitcdCHN = goods.firstUnitCNH
            this.editData.secdLawfUnitcd = goods.secondUnit
            this.editData.secdLawfUnitcdCHN = goods.secondUnitCNH
            this.$nextTick(_ => {
                // 设置法一/二数量
                this.setLawfSecdQty()
                // 选择商品规格
                this.openGoodsModel()
            })
        },
        // 处理商品编号失去焦点
        // 不足4位不跳转下一个input (TAPD_BUG:1020644)
        handleGoodsCodingBlur (event, index) {
            event.stopPropagation()
            const coding = this.editData.gdecd
            if (coding && coding.length >= 4) {
                event.target.blur()
                this.editIndex = index
                this.goodsCoding = coding
                this.goodsModalVisible = true
            } else {
                this.$Message.warning('请至少输入四位商品编码！')
            }
        },
        // 初始化table数据
        initData (list) {
            this.editIndex = -1
            this.selectList = []
            const keys = cargoLabelkeys.concat(cargoKeys)
            const _key = new Date().getTime()
            this.cargoData = list.map((item, index) => {
                let obj = {
                    _key: _key + index // // 设置唯一标识(批量删除的筛选条件TPAD:1007408)
                }
                // 初始化值
                keys.forEach(key => {
                    obj[key] = item[key] || ''
                })
                return obj
            })
            this.clearTableCurrentRow()
        },
        // 设置默认值
        setDefaultData (def = null) {
            // 根据模板获取的默认填充数据
            this.defGoodsInfo = def
        },
        // 获取数据
        getData () {
            return this.cargoData.map((item, index) => {
                let obj = { gdsSeqno: index + 1 }
                cargoKeys.forEach(key => {
                    obj[key] = item[key]
                })
                return obj
            })
        },
        // 校验是否存在编辑的数据
        validate (fn) {
            let result = this.editIndex < 0
            if (result) {
                const err = this.checkGoodsData(this.cargoData)
                result = err.length ? err : result
            }
            fn && fn(result)
            return new Promise((resolve, reject) => {
                resolve(result)
            })
        },
        // 获取商品列表中重复的商品料号的序号(','隔开)
        getRepeatGdsMtnoIndexs (gdsMtno, list) {
            let arr = []
            list.forEach((item, index) => {
                if (item.gdsMtno === gdsMtno) arr.push(index + 1)
            })
            return arr.length > 1 ? arr.join(',') : '' // 长度大于1则代表有重复的商品
        },
        checkGoodsData (list) {
            const fields = { 'putrecSeqno': '备案序号', 'gdsMtno': '商品料号', 'gdecd': '商品编码', 'gdsNm': ' 商品名称', 'gdsSpcfModelDesc': ' 规格型号', 'dclCurrcd': ' 币制', 'dclQty': '申报数量', 'dclUnitcd': '申报计量单位', 'lawfQty': '法定数量', 'lawfUnitcd': '法定计量单位', 'secdLawfQty': '第二法定数量', 'secdLawfUnitcd': '法定第二计量单位', 'dclUprcAmt': '企业申报单价', 'dclTotalAmt': '企业申报总价', 'natcd': '原产国(地区)', 'grossWt': '毛重', 'netWt': '净重', 'destinationNatcd': ' 最终目的国(地区)', 'lvyrlfModecd': '征免方式', 'ucnsVerno': '单耗版本号' }
            let result = []
            const rules = Object.keys(cargoRules)
            let repeatGds = '' // 记录重复的料号
            list.forEach((item, index) => {
                rules.forEach(key => {
                    let err = cargoRules[key].call(this, item[key], item)
                    // 增加入仓料号重复校验(TAPD:1007930)
                    // 判断料号字段、入仓模式 并且不是重复的料号
                    if (key == 'gdsMtno' && this.ieFlag === 'I' && item.gdsMtno && !repeatGds.includes(index + 1)) {
                        const str = this.getRepeatGdsMtnoIndexs(item.gdsMtno, list)
                        err = str ? `项号${str}的商品料号相同` : err
                        repeatGds = `${repeatGds},${str}`
                    }
                    err && result.push({
                        index: index + 1,
                        field: fields[key],
                        msg: err
                    })
                })
            })
            return result
        },
        // 复制所有数据(清空id等值) 给外部调用
        copyAllCargoData () {
            this.cargoData.forEach(item => {
                item.invtGoodsId = ''
            })
        },
        // 手册账号 + 备案序号 带出商品信息
        handlePutrecSeqno (v) {
            this.$emit('putrecSeqnoBlur', v, (res) => {
                if (res.data.code === '0000') {
                    // 没有数据时清空之前字段内容(TAPD:1007930)
                    let data = res.data.data.customsManualDetail && res.data.data.customsManualDetail[0] || null
                    if (!data) {
                        data = {}
                        const msg = res.data.data.message
                        msg && this.$Message.warning(msg)
                    }
                    const { codeTs, goodsName, gunit, gUnitName, goodsModel } = data
                    this.editData.gdecd = codeTs || ''
                    this.editData.gdsNm = goodsName || ''
                    this.editData.gdsSpcfModelDesc = goodsModel ? goodsModel.replace(/\s+/g, '|') : ''
                    this.editData.dclUnitcd = gunit || ''
                    this.editData.dclCurrcdCHN = gUnitName || ''
                    // 设置法一/二数量
                    this.setLawfSecdQty()
                } else {
                    this.$Message.error(res.data.msg)
                }
            })
        },
        // 获取系统生成的商品料号
        getSysGdsMtno (index = null) {
            if (this.ieFlag !== 'I' || !this.etpsNo) return ''
            const i = typeof index === 'number' ? index : this.cargoData.length + 1
            const code = ('000' + i).substr(-3)
            return this.etpsNo + code
        },
        // 点击规格型号 弹窗
        openGoodsModel () {
            const { gdecd, gdsSpcfModelDesc } = this.editData
            if (gdecd && gdecd.length === 10) {
                this.$refs.detailsModalRef.init(
                    gdecd,
                    gdsSpcfModelDesc,
                    'E', // E 表示出口||出境  I 表示进口||进境
                    false,
                    false
                )
            } else {
                this.$Message.warning('请输入10位商品编码')
            }
        },
        // 处理弹窗选择设置规格型号
        saveDetail (data) {
            this.editData.gdsSpcfModelDesc = data || ''
            this.$nextTick(() => {
                focusIndexInput(3, this.inputs)
            })
        },
        // 设置法一/二数量(TAPD_BUG:ID1021766)
        setLawfSecdQty () {
            const { lawfUnitcd, dclUnitcd, dclQty, secdLawfUnitcd } = this.editData
            if (lawfUnitcd && lawfUnitcd === dclUnitcd) {
                this.editData.lawfQty = dclQty || ''
            }
            // 若成交单位与法二单位一致，则法二数量栏自动取成交数量栏里面的值。(TAPD_BUG:ID1021766)
            if (secdLawfUnitcd && secdLawfUnitcd === dclUnitcd) {
                this.editData.secdLawfQty = dclQty || ''
            }
        },
        // 法二数量修改时判断 成交单位和法二单位是否一致 一致则同步成交数量 (TAPD_BUG:ID1021766)
        checkSecondGqty () {
            const { dclUnitcd, secdLawfQty, secdLawfUnitcd } = this.editData
            if (secdLawfUnitcd && secdLawfUnitcd === dclUnitcd && secdLawfQty) {
                this.editData.dclQty = secdLawfQty
            }
        },
        // 法一数量修改时判断 成交单位和法一单位是否一致 一致则同步成交数量 (TAPD_BUG:ID1021766)
        checkFirstGqty () {
            const { dclUnitcd, lawfQty, lawfUnitcd } = this.editData
            if (lawfUnitcd && lawfUnitcd === dclUnitcd && lawfQty) {
                this.editData.dclQty = lawfQty
            }
        },
        // 保留小数位： 总 2  单 4  数 5
        // 处理企业申报总价改变
        handleChangeTotal () {
            const total = Number(this.editData.dclTotalAmt) || 0
            const price = Number(this.editData.dclUprcAmt) || 0
            const dclQty = Number(this.editData.dclQty) || 0
            if (!total) return
            if (dclQty) {
                // 如果有数量 则计算单价
                this.editData.dclUprcAmt = evenRound(total / dclQty, 4)
            } else if (price) {
                // 如果没有数据 有单价   则计算数量
                this.editData.dclQty = evenRound(total / price, 5)
            }
        },
        // 处理申报数量改变
        handleChangedclQty () {
            const total = Number(this.editData.dclTotalAmt) || 0
            const price = Number(this.editData.dclUprcAmt) || 0
            const dclQty = Number(this.editData.dclQty) || 0
            if (!dclQty) return
            if (price) {
                // 如果有单价  则计算总价
                this.editData.dclTotalAmt = evenRound(dclQty * price, 2)
            } else if (total) {
                // 如果没有单价 有总价   则计算单价
                this.editData.dclUprcAmt = evenRound(total / dclQty, 4)
            }
            // 设置法一/二数量
            this.setLawfSecdQty()
        },
        // 处理企业申报单价改变
        handleChangePrice () {
            const total = Number(this.editData.dclTotalAmt) || 0
            const price = Number(this.editData.dclUprcAmt) || 0
            const dclQty = Number(this.editData.dclQty) || 0
            if (!price) return
            if (dclQty) {
                // 如果有数量  则计算总价
                this.editData.dclTotalAmt = evenRound(price * dclQty, 2)
            } else if (total) {
                // 如果没有数量 有总价   则计算数量
                this.editData.dclQty = evenRound(total / price, 5)
            }
        },
        // 处理企业内部编号改变
        handleEtpsNoChange (v) {
            // 入区（进口）才需要自动生成商品料号
            // 重新编排 商品的商品料号  企业内部编码 + 三位序号(不足往前补0)(TAPD:1007930)
            if (this.ieFlag === 'I' && v) {
                this.initCargoGdsMtno()
                if (this.editIndex >= 0) {
                    const code = ('000' + (this.editIndex + 1)).substr(-3)
                    this.editData.gdsMtno = v + code
                }
            }
        },
        // 处理商品料号回车带出商品数据
        handleGdsMtnoEnter () {
            const { gdsMtno } = this.editData
            // 出区 （出口）才需要查询
            if (this.ieFlag === 'E' && gdsMtno) {
                const templateType = this.templateType
                managementFuzzyQuery({
                    inventoryGoodsNo: gdsMtno,
                    templateType
                }).then(res => {
                    if (!res) return
                    // 字段对应接口返回字段
                    let fields = {
                        putrecSeqno: 'jgSerialNo',
                        gdecd: 'codeTs',
                        gdsNm: 'goodsName',
                        gdsSpcfModelDesc: 'goodsModel',
                        dclUnitcdCHN: 'gunitName',
                        dclUnitcd: 'gunit',
                        lawfUnitcdCHN: 'firstGunitName',
                        lawfUnitcd: 'firstGunit',
                        secdLawfUnitcdCHN: 'secondGunitName',
                        secdLawfUnitcd: 'secondGunit',
                        natcd: 'originCountry',
                        natcdCHN: 'originCountryName'
                    }
                    // 需要修改的字段集合
                    let keys = Object.keys(fields)
                    if (res.data.code === '0000') {
                        const data = res.data.data || {}
                        // ID1021609  出区 商品料号带出 商品编码、商品名称、规格型号、申报计量单位、法定计量单位、法二单位、原产国
                        keys.forEach(k => {
                            const field = fields[k]
                            this.editData[k] = data[field] || ''
                        })
                        // 判断 成交单位与法一/二单位是否相等并设置法一/二数量(TAPD_BUG:1020644)
                        this.setLawfSecdQty()
                    } else {
                        keys.forEach(k => { this.editData[k] = '' }) // 没有数据时清空之前的填写内容(TAPD:1007930)
                        this.$Message.warning(res.data.msg)
                    }
                })
            }
        }
    }
}
</script>
<style lang="less" scoped>
.addcargo {
    padding: 10px 0 6px;
    text-align: right;
    .form-title {
        float: left;
        color: #1291cc;
        margin-bottom: 10px;
    }
    button + button {
        margin-left: 8px;
    }
}
.text-ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cargo-details {
    position: relative;
    padding-right: 80px;
    .table-side {
        position: absolute;
        right: 0;
        top: 0;
        width: 80px;
        border-top: 1px solid #e7e7ed;
        border-right: 1px solid #e7e7ed;
        box-shadow: -2px 0 6px -2px rgba(0, 0, 0, 0.2);
        th {
            background-color: #f8f8f9;
            color: #383a4a;
            font-size: 13px;
            text-align: center;
            height: 30px;
            border-bottom: 1px solid #e7e7ed;
            font-weight: 700;
            vertical-align: middle;
        }
        td {
            width: 140px;
            height: 30px;
            text-align: center;
            color: #767884;
            vertical-align: middle;
            border-bottom: 1px solid #e7e7ed;
        }
        button {
            color: #1177e8;
        }
    }
}

</style>
<style lang="less">
#cargo_table {
    width: 100%;
    .required::before{
        content: "*";
        font-weight: normal;
        display: inline-block;
        margin-right: 2px;
        font-family: SimSun;
        font-size: 12px;
        color: #ed4014;
    }
    td .cell {
        padding: 0 2px;
    }
}
</style>
